﻿using SUNRPA.BROWSER.BRIDGE.domain;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SUNRPA.BROWSER.BRIDGE.util {
    public class BrowserCommUtil {
        public static LogUtil logger = new LogUtil(typeof(BrowserCommUtil));
        private static Stream stdin = Console.OpenStandardInput();
        private static Stream stdout = Console.OpenStandardOutput();
        private static CancellationTokenSource workerSwitch = new CancellationTokenSource();
        private static AutoResetEvent resetEvent = new AutoResetEvent(false);

        public static void Dispose() {
            stdin.Dispose();
            stdout.Dispose();
        }

        public static void CloseBrowserCommWorker() { 
            workerSwitch.Cancel();
        }

        private static BridgeResponse ReadMsgFromBrowser(Object resp){
            byte[] bytes = new byte[4];
            stdin.Read(bytes, 0, 4);
            int length = BitConverter.ToInt32(bytes, 0);
            byte[] buffer = new byte[length];
            stdin.Read(buffer, 0, length);
            return DataUtil.DeSerializeJson<BridgeResponse>(Encoding.UTF8.GetString(buffer), false);
        }

        public static BridgeResponse WriteMsgToBrowser(object msg){
            lock(stdout) {
                //禁止重复读写数据
                byte[] msgbyte = Encoding.UTF8.GetBytes(DataUtil.ObjectJsonSerializer(msg, false));
                //写长度（程序到浏览器）
                stdout.WriteByte((byte)((msgbyte.Length >> 0) & 0xFF));
                stdout.WriteByte((byte)((msgbyte.Length >> 8) & 0xFF));
                stdout.WriteByte((byte)((msgbyte.Length >> 16) & 0xFF));
                stdout.WriteByte((byte)((msgbyte.Length >> 24) & 0xFF));
                stdout.Write(msgbyte, 0, msgbyte.Length);
                stdout.Flush();
                return ReadMsgFromBrowser(2000);
            }
        }

        public static Task BeginListerWorker() { 
            Task task = Task.Run(() => {
                while(!workerSwitch.Token.IsCancellationRequested) {
                    try {
                        BridgeResponse browserResp = WriteMsgToBrowser(new BrowserRequest(){method="HEARTBEAT" });
                        if("close".Equals(browserResp.msg) || !CommunicationCode.OK.Equals(browserResp.code)) {
                            logger.Info("浏览器插件已关闭，关闭中间程序");
                            CloseBrowserCommWorker();
                            NamedPipeServerUtil.CancelServerWorker();
                        }
                        Thread.Sleep(1000);
                    } catch(Exception e){
                        logger.Error("中间程序与浏览器心跳监测错误，请检查浏览器插件", e);
                        CloseBrowserCommWorker();
                        NamedPipeServerUtil.CancelServerWorker();
                    }
                }
                logger.Info("浏览器监听线程结束");
            });
            return task;
        }
    }
}
